/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estructurassa.expertos;

import estructurassa.entidades.CentroTrabajo;
import estructurassa.entidades.DetalleOrden;
import estructurassa.entidades.EtapaFabricacion;
import estructurassa.entidades.Maquinaria;
import estructurassa.entidades.Material;
import estructurassa.entidades.OrdenDeProduccion;
import estructurassa.expertos.excepciones.ABMMaquinariaException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import persistencia.Conexion;
import persistencia.Fachada;
import persistencia.exceptions.ExcepcionFachada;

/**
 *
 * @author diego
 */
public class ExpertoABMMaquinaria implements Experto {

    public void guardar(Maquinaria maquinaria, CentroTrabajo centroTrabajo) throws ABMMaquinariaException {
        validarMaquinaria(maquinaria);
        validarExistencia(maquinaria);
        String codigo;
        codigo = ((ExpertoCodigo) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.GENERAR_CODIGO)).generarCodigo(maquinaria, centroTrabajo);
        maquinaria.setCodigo(codigo);
        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(maquinaria);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            Logger.getLogger(ExpertoABMMaquinaria.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void guardar(Maquinaria maquinaria) throws ABMMaquinariaException {
        validarMaquinaria(maquinaria);
        validarExistencia(maquinaria);
        String codigo;
        codigo = ((ExpertoCodigo) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.GENERAR_CODIGO)).generarCodigo(maquinaria);
        maquinaria.setCodigo(codigo);
        try {
            Conexion.getInstancia().iniciarTX();
            Fachada.getInstancia().guardar(maquinaria);
            Conexion.getInstancia().confirmarTx();
        } catch (ExcepcionFachada ex) {
            Conexion.getInstancia().deshacerTx();
            Logger.getLogger(ExpertoABMMaquinaria.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public List buscarMaquinarias() {
        return Fachada.getInstancia().buscar(Maquinaria.class, null);
    }
    public List buscarMaquinariasVigentes() {
        Criteria vigente = Fachada.getInstancia().crearCriterio(Maquinaria.class).add(Restrictions.eq("vigente", true));
        return Fachada.getInstancia().buscar(Maquinaria.class, vigente);
    }

    public List buscarMaquinarias(String nombre) {
        Criteria criterioNombre = Fachada.getInstancia().crearCriterio(Maquinaria.class);
        criterioNombre.add(Restrictions.ilike("nombre", nombre));
        return Fachada.getInstancia().buscar(Material.class, criterioNombre);
    }

    private void validarMaquinaria(Maquinaria maquinaria) throws ABMMaquinariaException {
        if (maquinaria.getNombre().length() == 0) {
            throw new ABMMaquinariaException("Falta nombre");
        }
        if (maquinaria.getConsumo() == -1) {
            throw new ABMMaquinariaException("Falta Consumo");
        }
        if (maquinaria.getUnidadConsumo().length() == 0) {
            throw new ABMMaquinariaException("Falta unidad de consumo");
        }
    }

    private void validarExistencia(Maquinaria maquinaria) throws ABMMaquinariaException {
        if (maquinaria.getId() == null || maquinaria.getId() == 0) {
            return;
        
        } else {
            Criteria nombreMaquinaria = Fachada.getInstancia().crearCriterio(Material.class);
            nombreMaquinaria.add(Restrictions.eq("nombre", maquinaria.getNombre()).ignoreCase());
            if (!Fachada.getInstancia().buscar(Material.class, nombreMaquinaria).isEmpty()) {
                throw new ABMMaquinariaException("Material ya existente");
            }
        }
    }

    public void darDeBaja(Maquinaria maquinaria) throws ABMMaquinariaException, ExcepcionFachada {
        boolean encontrado = false;
        Criteria criterioOrdenActiva = Fachada.getInstancia().crearCriterio(OrdenDeProduccion.class);
        criterioOrdenActiva.add(Restrictions.eq("ordenActiva", true));
        List ordenesActivas = Fachada.getInstancia().buscar(OrdenDeProduccion.class, criterioOrdenActiva);

        for (Object orden : ordenesActivas) {
            List detalles = ((OrdenDeProduccion) orden).getListaDetalles();
            for (Object detalle : detalles) {
                List etapas = ((DetalleOrden) detalle).getProductoTerminado().getRutaFabricacion().getEstapasFabricacion();
                for (Object etapa : etapas) {
                    if (maquinaria == ((EtapaFabricacion) etapa).getMaquina()) {
                        encontrado = true;
                    }
                }
            }
        }
        if (!encontrado) {
            Fachada.getInstancia().eliminar(maquinaria);
        } else {
            JOptionPane.showMessageDialog(null, "Maquinaria actualmente necesaria para una orden pendiente", "Notificación", JOptionPane.INFORMATION_MESSAGE);
            throw new ABMMaquinariaException("No se pudo eliminar la maquinaria");
        }
    }
}
